package com.godpaper.the5elements.busniess.factorys
{
	import com.godpaper.the5elements.model.BoardModel;
	import com.godpaper.the5elements.model.PiecesModel;
	import com.godpaper.the5elements.util.DebugUtil;
	import com.godpaper.the5elements.views.ChessBoard;
	import com.godpaper.the5elements.views.components.GasketButton;
	import com.godpaper.the5elements.views.components.PieceButton;
	
	import de.polygonal.ds.GraphArc;
	import de.polygonal.ds.GraphNode;
	
	import jp.dip.hael.gameai.graph.Node;
	import jp.dip.hael.gameai.graph.WeightedEdge;
	import jp.dip.hael.gameai.graph.searcher.Dijkstra;
	
	import mx.core.IFlexDisplayObject;
	import mx.logging.ILogger;
	import mx.logging.Log;

	/**
	 * 
	 * A ButtonFactory providering PiecesButton and GasketButton
	 * 
	 */	
	public class ButtonFactory
	{
		private static var chessBoard:ChessBoard;
		private static var iPieceButton:IFlexDisplayObject;
		
		public static const FLAG_RED:String = "red";
		public static const FLAG_BLUE:String = "blue";
		private static const MAX_PIECE_NUM:int = 4;
		public static const MAX_GASKET_NUM:int = 12;
		public static const TYPE_PIECE:String = "pieceButton";
		public static const TYPE_GASKET:String = "gasketButton";
		
		private static const log:ILogger = mx.logging.Log.getLogger("ButtonFactory");
		
		public function ButtonFactory()
		{
			//TODO: implement function
		}
		
		public static function produce(type:String, boardTarget:ChessBoard,flagColor:String=null):void
		{
			//restore board;
			chessBoard = boardTarget;
			switch(type)
			{
				case TYPE_PIECE:
					if(flagColor==FLAG_RED)
					{
						//Postive RED
						for(var i:int=0;i<MAX_PIECE_NUM;i++)
						{
							var pieceButtonRED:PieceButton = new PieceButton(); 
							/*iPieceButton = PopUpManager.createPopUp(chessBoard,PieceButton);
							PopUpManager.centerPopUp(iPieceButton);*/
							pieceButtonRED.styleName = PieceButton.BUTTON_STYLE_NAME_RED;
							pieceButtonRED.name = pieceButtonRED.pieceVO.name = PieceButton.NAME_PREFIX_RED.concat(i.toString());
							pieceButtonRED.label = i.toString();
//							pieceButtonRED.enabled = false;
							pieceButtonRED.mouseChildren = false;
							pieceButtonRED.mouseEnabled = false;
							switch(i)
							{
								case 0:
								case 1:
									pieceButtonRED.x = chessBoard.hRegularRect.x+(chessBoard.width-2*ChessBoard.PADDING)/3*i -pieceButtonRED.width/2;
									pieceButtonRED.y = chessBoard.hRegularRect.y-pieceButtonRED.height/2;
									pieceButtonRED.pieceVO.position = [i+2,1];
									BoardModel.getInstance().gamePosition.sett(i+2,1,pieceButtonRED);
									break;
								case 2:
								case 3:
									pieceButtonRED.x = chessBoard.vRegularRect.width/3*(i-1) -pieceButtonRED.width/2+ChessBoard.PADDING;
									pieceButtonRED.y = chessBoard.vRegularRect.y-pieceButtonRED.height/2;
									pieceButtonRED.pieceVO.position = [i,2];
									BoardModel.getInstance().gamePosition.sett(i,2,pieceButtonRED);
								default:
									break;	
							}
							BoardModel.getInstance().gamePosition.sett(0,0,"boundary");
							BoardModel.getInstance().gamePosition.sett(3,0,"boundary");
							//add to chessBoard
							chessBoard.addChild(pieceButtonRED);
							//push to collection;
							PiecesModel.getInstance().redPiecesCollection.addItem(pieceButtonRED);
						}
						
					}else
					{
						//Nagetive BLUE
						for(var j:int=0;j<MAX_PIECE_NUM;j++)
						{
							/*iPieceButton = PopUpManager.createPopUp(chessBoard,PieceButton);
							PopUpManager.centerPopUp(iPieceButton);*/
							var pieceButtonBLUE:PieceButton = new PieceButton();
							pieceButtonBLUE.styleName = PieceButton.BUTTON_STYLE_NAME_BLUE;
							pieceButtonBLUE.name = pieceButtonBLUE.pieceVO.name = PieceButton.NAME_PREFIX_BLUE.concat(j.toString());
							pieceButtonBLUE.label = j.toString();
							switch(j)
							{
								case 0:
								case 1:
									pieceButtonBLUE.x = chessBoard.vRegularRect.width/3*(j+1) -pieceButtonBLUE.width/2+ChessBoard.PADDING;
									pieceButtonBLUE.y = chessBoard.vRegularRect.y+chessBoard.vRegularRect.height-pieceButtonBLUE.height/2;
									pieceButtonBLUE.pieceVO.position = [j+2,3];
									BoardModel.getInstance().gamePosition.sett(j+2,3,pieceButtonBLUE);
									break;
								case 2:
								case 3:
									pieceButtonBLUE.x = chessBoard.hRegularRect.x+(chessBoard.width-2*ChessBoard.PADDING)/3*(j-2) -pieceButtonBLUE.width/2;
									pieceButtonBLUE.y = chessBoard.hRegularRect.y+chessBoard.hRegularRect.height-pieceButtonBLUE.height/2;
									pieceButtonBLUE.pieceVO.position = [j,4];
									BoardModel.getInstance().gamePosition.sett(j,4,pieceButtonBLUE);
									break;
								default:
									break;	
							}
							//add boundary to gamePosition;
							BoardModel.getInstance().gamePosition.sett(0,0,"boundary");
							BoardModel.getInstance().gamePosition.sett(1,0,"boundary");
							BoardModel.getInstance().gamePosition.sett(2,0,"boundary");
							BoardModel.getInstance().gamePosition.sett(3,0,"boundary");
							BoardModel.getInstance().gamePosition.sett(4,0,"boundary");
							BoardModel.getInstance().gamePosition.sett(5,0,"boundary");
							
							BoardModel.getInstance().gamePosition.sett(0,1,"boundary");
							BoardModel.getInstance().gamePosition.sett(1,1,"boundary");
							BoardModel.getInstance().gamePosition.sett(4,1,"boundary");
							BoardModel.getInstance().gamePosition.sett(5,1,"boundary");
							
							BoardModel.getInstance().gamePosition.sett(0,2,"boundary");
							BoardModel.getInstance().gamePosition.sett(5,2,"boundary");
							
							BoardModel.getInstance().gamePosition.sett(0,3,"boundary");
							BoardModel.getInstance().gamePosition.sett(5,3,"boundary");
							
							BoardModel.getInstance().gamePosition.sett(0,4,"boundary");
							BoardModel.getInstance().gamePosition.sett(1,4,"boundary");
							BoardModel.getInstance().gamePosition.sett(4,4,"boundary");
							BoardModel.getInstance().gamePosition.sett(5,4,"boundary");
							
							BoardModel.getInstance().gamePosition.sett(0,5,"boundary");
							BoardModel.getInstance().gamePosition.sett(1,5,"boundary");
							BoardModel.getInstance().gamePosition.sett(2,5,"boundary");
							BoardModel.getInstance().gamePosition.sett(3,5,"boundary");
							BoardModel.getInstance().gamePosition.sett(4,5,"boundary");
							BoardModel.getInstance().gamePosition.sett(5,5,"boundary");
							//add to chessBoard
							chessBoard.addChild(pieceButtonBLUE);
							//push to collection;
							PiecesModel.getInstance().bluePiecesCollection.addItem(pieceButtonBLUE);
						}
						log.info("initialized gamePosition:{0}",BoardModel.getInstance().gamePosition.dump());
					}
					break;
				case TYPE_GASKET:
					for(var ii:int=0;ii<MAX_GASKET_NUM;ii++)
					{
						var gasketButton:GasketButton = new GasketButton();
						gasketButton.name = GasketButton.NAME_PREFIX.concat(ii.toString());
						gasketButton.label = ii.toString();
						var gasketNode:GraphNode;
						var gasketArc:GraphArc;
						switch(ii)
						{
							case 0:
							case 1:
								gasketButton.x = chessBoard.hRegularRect.x+(chessBoard.width-2*ChessBoard.PADDING)/3*ii -gasketButton.width/2;
								gasketButton.y = chessBoard.hRegularRect.y-gasketButton.height/2;
								gasketButton.position = [ii+2,1];
								gasketNode = new GraphNode(gasketButton);
//								BoardModel.getInstance().gameGraph.addNode(gasketNode,ii);
								BoardModel.getInstance().gasketsPosition.sett(ii+2,1,gasketButton);
								break;
							case 2:
							case 3:
							case 4:
							case 5:
								gasketButton.x = chessBoard.vRegularRect.width/3*(ii-2) -gasketButton.width/2+ChessBoard.PADDING;
								gasketButton.y = chessBoard.vRegularRect.y-gasketButton.height/2;
								gasketButton.position = [ii-1,2];
								gasketNode = new GraphNode(gasketButton);
//								BoardModel.getInstance().gameGraph.addNode(gasketNode,ii);
								BoardModel.getInstance().gasketsPosition.sett(ii-1,2,gasketButton);
								break;
							case 6:
							case 7:
							case 8:
							case 9:
								gasketButton.x = chessBoard.vRegularRect.width/3*(ii-6) -gasketButton.width/2+ChessBoard.PADDING;
								gasketButton.y = chessBoard.vRegularRect.y+chessBoard.vRegularRect.height-gasketButton.height/2;
								gasketButton.position = [ii-5,3];
								gasketNode = new GraphNode(gasketButton);
//								BoardModel.getInstance().gameGraph.addNode(gasketNode,ii);
								BoardModel.getInstance().gasketsPosition.sett(ii-5,3,gasketButton);
								break;
							case 10:
							case 11:
								gasketButton.x = chessBoard.hRegularRect.x+(chessBoard.width-2*ChessBoard.PADDING)/3*(ii-10) -gasketButton.width/2;
								gasketButton.y = chessBoard.hRegularRect.y+chessBoard.hRegularRect.height-gasketButton.height/2;
								gasketButton.position = [ii-8,4];
								gasketNode = new GraphNode(gasketButton);
//								BoardModel.getInstance().gameGraph.addNode(gasketNode,ii);
								BoardModel.getInstance().gasketsPosition.sett(ii-8,4,gasketButton);
								break;
							default:
								break;	
						}
						//another way.using 
						BoardModel.getInstance().gameGraph.addNode(new Node(ii));
						//add to chessBoard
						chessBoard.rawChildren.addChild(gasketButton);
						PiecesModel.getInstance().gasketCollection.addItem(gasketButton);
						
					}	
					log.info("initilized gasketPosition@ButtonFactory:{0}",BoardModel.getInstance().gasketsPosition.dump());	
					//connect nodes with arc,and set gasketButtons relationship 
//					BoardModel.getInstance().gameGraph.addArc(0,1,1);
					(PiecesModel.getInstance().gasketCollection.getItemAt(0) as GasketButton).right =
						(PiecesModel.getInstance().gasketCollection.getItemAt(1) as GasketButton);
						
//					BoardModel.getInstance().gameGraph.addArc(0,3,1);
					(PiecesModel.getInstance().gasketCollection.getItemAt(0) as GasketButton).bottom =
						(PiecesModel.getInstance().gasketCollection.getItemAt(3) as GasketButton);
					
//					BoardModel.getInstance().gameGraph.addArc(1,0,1);
					(PiecesModel.getInstance().gasketCollection.getItemAt(1) as GasketButton).left =
						(PiecesModel.getInstance().gasketCollection.getItemAt(0) as GasketButton);
//					BoardModel.getInstance().gameGraph.addArc(1,4,1);
					(PiecesModel.getInstance().gasketCollection.getItemAt(1) as GasketButton).bottom =
						(PiecesModel.getInstance().gasketCollection.getItemAt(4) as GasketButton);
					
//					BoardModel.getInstance().gameGraph.addArc(2,3,1);
					(PiecesModel.getInstance().gasketCollection.getItemAt(2) as GasketButton).right =
						(PiecesModel.getInstance().gasketCollection.getItemAt(3) as GasketButton);
//					BoardModel.getInstance().gameGraph.addArc(2,6,1);
					BoardModel.getInstance().gameGraph.addEdge(new WeightedEdge(2,6,1));
					(PiecesModel.getInstance().gasketCollection.getItemAt(2) as GasketButton).bottom =
						(PiecesModel.getInstance().gasketCollection.getItemAt(6) as GasketButton);
					
//					BoardModel.getInstance().gameGraph.addArc(3,0,1);
					(PiecesModel.getInstance().gasketCollection.getItemAt(3) as GasketButton).top =
						(PiecesModel.getInstance().gasketCollection.getItemAt(0) as GasketButton);
//					BoardModel.getInstance().gameGraph.addArc(3,2,1);
					BoardModel.getInstance().gameGraph.addEdge(new WeightedEdge(3,2,1));
					(PiecesModel.getInstance().gasketCollection.getItemAt(3) as GasketButton).left =
						(PiecesModel.getInstance().gasketCollection.getItemAt(2) as GasketButton);
//					BoardModel.getInstance().gameGraph.addArc(3,4,1);
					(PiecesModel.getInstance().gasketCollection.getItemAt(3) as GasketButton).right =
						(PiecesModel.getInstance().gasketCollection.getItemAt(4) as GasketButton);
//					BoardModel.getInstance().gameGraph.addArc(3,7,1);
					(PiecesModel.getInstance().gasketCollection.getItemAt(3) as GasketButton).bottom =
						(PiecesModel.getInstance().gasketCollection.getItemAt(7) as GasketButton);
					
//					BoardModel.getInstance().gameGraph.addArc(4,1,1);
					(PiecesModel.getInstance().gasketCollection.getItemAt(4) as GasketButton).top =
						(PiecesModel.getInstance().gasketCollection.getItemAt(1) as GasketButton);
//					BoardModel.getInstance().gameGraph.addArc(4,3,1);
					(PiecesModel.getInstance().gasketCollection.getItemAt(4) as GasketButton).left =
						(PiecesModel.getInstance().gasketCollection.getItemAt(3) as GasketButton);
//					BoardModel.getInstance().gameGraph.addArc(4,5,1);
					BoardModel.getInstance().gameGraph.addEdge(new WeightedEdge(4,5,1));
					(PiecesModel.getInstance().gasketCollection.getItemAt(4) as GasketButton).right =
						(PiecesModel.getInstance().gasketCollection.getItemAt(5) as GasketButton);
//					BoardModel.getInstance().gameGraph.addArc(4,8,1);
					(PiecesModel.getInstance().gasketCollection.getItemAt(4) as GasketButton).bottom =
						(PiecesModel.getInstance().gasketCollection.getItemAt(8) as GasketButton);
					
//					BoardModel.getInstance().gameGraph.addArc(5,4,1);
					(PiecesModel.getInstance().gasketCollection.getItemAt(5) as GasketButton).left =
						(PiecesModel.getInstance().gasketCollection.getItemAt(4) as GasketButton);
//					BoardModel.getInstance().gameGraph.addArc(5,9,1);
					BoardModel.getInstance().gameGraph.addEdge(new WeightedEdge(5,9,1));
					(PiecesModel.getInstance().gasketCollection.getItemAt(5) as GasketButton).bottom =
						(PiecesModel.getInstance().gasketCollection.getItemAt(9) as GasketButton);
					
//					BoardModel.getInstance().gameGraph.addArc(6,2,1);
					BoardModel.getInstance().gameGraph.addEdge(new WeightedEdge(6,2,1));
					(PiecesModel.getInstance().gasketCollection.getItemAt(6) as GasketButton).top =
						(PiecesModel.getInstance().gasketCollection.getItemAt(2) as GasketButton);
//					BoardModel.getInstance().gameGraph.addArc(6,7,1);
					(PiecesModel.getInstance().gasketCollection.getItemAt(6) as GasketButton).right =
						(PiecesModel.getInstance().gasketCollection.getItemAt(7) as GasketButton);
					
//					BoardModel.getInstance().gameGraph.addArc(7,3,1);
					(PiecesModel.getInstance().gasketCollection.getItemAt(7) as GasketButton).top =
						(PiecesModel.getInstance().gasketCollection.getItemAt(3) as GasketButton);
//					BoardModel.getInstance().gameGraph.addArc(7,6,1);
					BoardModel.getInstance().gameGraph.addEdge(new WeightedEdge(7,6,1));
					(PiecesModel.getInstance().gasketCollection.getItemAt(7) as GasketButton).left =
						(PiecesModel.getInstance().gasketCollection.getItemAt(6) as GasketButton);
//					BoardModel.getInstance().gameGraph.addArc(7,8,1);
					(PiecesModel.getInstance().gasketCollection.getItemAt(7) as GasketButton).right =
						(PiecesModel.getInstance().gasketCollection.getItemAt(8) as GasketButton);
//					BoardModel.getInstance().gameGraph.addArc(7,10,1);
					(PiecesModel.getInstance().gasketCollection.getItemAt(7) as GasketButton).bottom =
						(PiecesModel.getInstance().gasketCollection.getItemAt(10) as GasketButton);
					
//					BoardModel.getInstance().gameGraph.addArc(8,4,1);
					(PiecesModel.getInstance().gasketCollection.getItemAt(8) as GasketButton).top =
						(PiecesModel.getInstance().gasketCollection.getItemAt(4) as GasketButton);
//					BoardModel.getInstance().gameGraph.addArc(8,7,1);
					(PiecesModel.getInstance().gasketCollection.getItemAt(8) as GasketButton).left =
						(PiecesModel.getInstance().gasketCollection.getItemAt(7) as GasketButton);
//					BoardModel.getInstance().gameGraph.addArc(8,9,1);
					BoardModel.getInstance().gameGraph.addEdge(new WeightedEdge(8,9,1));
					(PiecesModel.getInstance().gasketCollection.getItemAt(8) as GasketButton).right =
						(PiecesModel.getInstance().gasketCollection.getItemAt(9) as GasketButton);
//					BoardModel.getInstance().gameGraph.addArc(8,11,1);
					(PiecesModel.getInstance().gasketCollection.getItemAt(8) as GasketButton).bottom =
						(PiecesModel.getInstance().gasketCollection.getItemAt(11) as GasketButton);
					
//					BoardModel.getInstance().gameGraph.addArc(9,5,1);
					BoardModel.getInstance().gameGraph.addEdge(new WeightedEdge(9,5,1));
					(PiecesModel.getInstance().gasketCollection.getItemAt(9) as GasketButton).top =
						(PiecesModel.getInstance().gasketCollection.getItemAt(5) as GasketButton);
//					BoardModel.getInstance().gameGraph.addArc(9,8,1);
					(PiecesModel.getInstance().gasketCollection.getItemAt(9) as GasketButton).left =
						(PiecesModel.getInstance().gasketCollection.getItemAt(8) as GasketButton);
					
//					BoardModel.getInstance().gameGraph.addArc(10,7,1);
					(PiecesModel.getInstance().gasketCollection.getItemAt(10) as GasketButton).top =
						(PiecesModel.getInstance().gasketCollection.getItemAt(7) as GasketButton);
//					BoardModel.getInstance().gameGraph.addArc(10,11,1);
					(PiecesModel.getInstance().gasketCollection.getItemAt(10) as GasketButton).right =
						(PiecesModel.getInstance().gasketCollection.getItemAt(11) as GasketButton);
					
//					BoardModel.getInstance().gameGraph.addArc(11,8,1);
					(PiecesModel.getInstance().gasketCollection.getItemAt(11) as GasketButton).top =
						(PiecesModel.getInstance().gasketCollection.getItemAt(8) as GasketButton);
//					BoardModel.getInstance().gameGraph.addArc(11,10,1);
					(PiecesModel.getInstance().gasketCollection.getItemAt(11) as GasketButton).left =
						(PiecesModel.getInstance().gasketCollection.getItemAt(10) as GasketButton);
					
					log.info("----BoardGraph graphNode test begin---");
					log.info("initilized GameGraph@ButtonFactory:{0}",DebugUtil.dumpGameGraph());			
//					trace("initilized GameGraph@ButtonFactory:",BoardModel.getInstance().gameGraph);
					var searcher:Dijkstra = new Dijkstra(BoardModel.getInstance().gameGraph);
					searcher.search(8,5);
					for(var p:int=0;p<searcher.path.length;p++)
					{
						log.info("findPath(8,5):{0}",searcher.path[p].dump());
					}
					log.info("----BoardGraph graphNode test end----");
					
					break;
					
				default:
					break;		
			}
			
			
		}
		
		/*protected static function get chessBoardPoint():Point
		{
			return Application.application.localToGlobal(new Point(chessBoard.x,chessBoard.y));
		}*/
		
		/*protected static function get pieceButton():PieceButton
		{
			return iPieceButton as PieceButton;
		}*/
	}
}